package com.benjaminwan.read.free.model

import android.view.View
import android.widget.CompoundButton
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import com.benjaminwan.read.free.model.enums.ItemType
import com.benjaminwan.read.free.utils.getString
import com.mywork.swipemenulayout.SwipeMenuItem
import com.mywork.swipemenulayout.SwipeMenuLayout

data class ItemConfig @JvmOverloads constructor(
    val isDebug: Boolean = false,
    val header: String = "",
    val borderWidth: Int = 0,
    val type: ItemType = ItemType.Switch,
    @StringRes val titleId: Int = 0,
    val titleStr: String = "",
    @DrawableRes val icon: Int = 0,
    val rightMenu: List<SwipeMenuItem> = emptyList(),
    inline val visibilityFuc: (() -> Int) = { View.VISIBLE },
    inline val enableFunc: (() -> Boolean) = { true },
    inline val checkableFunc: (() -> Boolean) = { true },
    inline val checkFunc: (() -> Boolean) = { true },
    inline val leftTextFunc: (() -> String) = { "" },
    inline val rightTextFunc: (() -> String) = { "" },
    inline val centerTextFunc: (() -> String) = { "" },
    inline val click: ((view: View) -> Unit) = {},
    inline val checkedChange: ((view: CompoundButton, isChecked: Boolean) -> Unit),
    inline val rightMenuClick: ((swipe: SwipeMenuLayout, pos: Int, view: View?) -> Unit)
) {
    private val title: String
        get() = if (titleId != 0) getString(titleId) else titleStr

    val visibility: Int
        get() = visibilityFuc()

    val isEnabled: Boolean
        get() = enableFunc()

    val isCheckable: Boolean
        get() = checkableFunc()

    val isChecked: Boolean
        get() = checkFunc()

    val leftText: String
        get() = if (title.isNotEmpty()) title else leftTextFunc()

    val rightText: String
        get() = rightTextFunc()

    val centerText: String
        get() = centerTextFunc()
}

@DslMarker
annotation class ItemConfigDsl

/**
 * type定义：
 * 0:switch 开关样式
 * 1:text 文字样式
 * */

@ItemConfigDsl
class ItemConfigBuilder {
    var isDebug: Boolean = false

    var header: String = ""

    var borderWidth: Int = 0

    var type: ItemType = ItemType.Switch

    @StringRes
    var titleId: Int = 0

    var titleStr: String = ""

    @DrawableRes
    var icon: Int = 0

    private val rightMenuList: MutableList<SwipeMenuItem> = mutableListOf()
    var rightMenu: List<SwipeMenuItem>
        get() = rightMenuList
        set(value) {
            rightMenuList.addAll(value)
        }

    private val groupList: MutableList<Int> = mutableListOf()
    var groupShow: List<Int>
        get() = groupList
        set(value) {
            groupList.addAll(value)
        }

    var visibilityFunc: (() -> Int) = { View.VISIBLE }

    var enableFunc: (() -> Boolean) = { true }

    var checkableFunc: (() -> Boolean) = { true }

    var optionFunc: (() -> List<ItemOption>) = { emptyList() }

    var checkFunc: (() -> Boolean) = { false }

    var leftTextFunc: (() -> String) = { "" }

    var rightTextFunc: (() -> String) = { "" }

    var centerTextFunc: (() -> String) = { "" }

    var click: ((view: View) -> Unit) = { view -> }

    var checkedChange: ((view: CompoundButton, isChecked: Boolean) -> Unit) = { view, isChecked -> }

    var rightMenuClick: ((swipe: SwipeMenuLayout, pos: Int, view: View?) -> Unit) =
        { swipe, pos, view -> }

    fun build(): ItemConfig =
        ItemConfig(
            isDebug, header, borderWidth, type, titleId, titleStr, icon, rightMenu,
            visibilityFunc, enableFunc, checkableFunc, checkFunc,
            leftTextFunc, rightTextFunc, centerTextFunc, click, checkedChange, rightMenuClick
        )

    val title: String
        get() = if (titleId != 0) getString(titleId) else titleStr

    val visibility: Int
        get() = visibilityFunc()

    val isEnabled: Boolean
        get() = enableFunc()

    val options: List<ItemOption>
        get() = optionFunc()

    val isChecked: Boolean
        get() = checkFunc()

    val leftText: String
        get() = if (title.isNotEmpty()) title else leftTextFunc()

    val rightText: String
        get() = rightTextFunc()

    val centerText: String
        get() = centerTextFunc()

}

inline fun itemConfig(block: ItemConfigBuilder.() -> Unit): ItemConfig =
    ItemConfigBuilder().apply(block).build()

@ItemConfigDsl
class ListItemConfigAdder : ArrayList<ItemConfig>() {
    inline fun itemConfig(block: ItemConfigBuilder.() -> Unit) {
        add(ItemConfigBuilder().apply(block).build())
    }

    fun itemConfig(config: ItemConfig) {
        add(config)
    }

    fun listOfItemConfig(configs: List<ItemConfig>) {
        addAll(configs)
    }

}

inline fun listOfItemConfig(block: ListItemConfigAdder.() -> Unit): List<ItemConfig> =
    ListItemConfigAdder().apply(block)